// File: XPhysicPreprocessor.h
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=link-me
//--------------------------------------------------------------------------------------

#ifdef _MSC_VER
#pragma once
#endif

#ifndef KMP_PREPROCESSOR_H
#define KMP_PREPROCESSOR_H

#include "kmp_exp.h"

/**
Compiler define
*/
#if (defined(_MSC_VER)  || defined(XOMP_VC)) && (!defined(__INTEL_COMPILER) || !defined(XOMP_ICL))
#	define KMP_VC 1
#undef KMP_COMPILER_STR
#	define KMP_COMPILER_STR "vc"
#   if _MSC_VER == 1200
#		define KMP_VC6 1
#   elif _MSC_VER == 1300
#		define KMP_VC7 1
#   elif _MSC_VER == 1400
#       define KMP_VC8 1
#   elif _MSC_VER == 1500
#       define KMP_VC9 1
#   elif _MSC_VER == 1600
#		define KMP_VC10 1
#   elif _MSC_VER == 1700
#		define KMP_VC11 1
#   elif _MSC_VER == 1800
#		define KMP_VC12 1
#	else
#pragma error "add your vc compiler version "
#	endif
#elif defined(_clang_)
#define KMP_CLANG 1
#undef KMP_COMPILER_STR
#	define KMP_COMPILER_STR "clang"
#elif defined( __INTEL_COMPILER )
#		define KMP_ICC 1
#undef KMP_COMPILER_STR
#	define KMP_COMPILER_STR "icl"
#if   __INTEL_COMPILER == 1010
#define KMP_ICC101 1
#elif __INTEL_COMPILER == 1100
#define KMP_ICC110 1
#elif __INTEL_COMPILER == 1110
#define KMP_ICC111 1
#elif __INTEL_COMPILER == 1200
#define KMP_ICC120 1
#elif __INTEL_COMPILER == 1210
#define KMP_ICC121 1
#elif __INTEL_COMPILER == 1300
#define KMP_ICC13 1
#elif __INTEL_COMPILER == 1310
#define KMP_ICC131 1
#elif __INTEL_COMPILER == 1400
#define KMP_ICC14 1
#elif __INTEL_COMPILER == 1410
#define KMP_ICC141 1
#elif __INTEL_COMPILER == 9999
#define KMP_ICC9999 1
#else
#pragma error "add your icc compiler version "
#endif
#elif defined( __GNUC__ )
# define KMP_GCC 1
#else
#	pragma error "Unknown compiler"
#	pragma error "Compiler needs to be implemented"
#endif


/**
Platform define
*/
#ifdef KMP_VC
#	if defined(_XBOX_ONE)
#		define KMP_XBOXONE 1
#		define KMP_X64 1
#		define KMP_INTRINSICS 1
#		define KMP_DIRECTKMPATH 1
#		define KMP_ARCHSTR "XOne"
#	elif defined(_M_IX86)
#		define KMP_X86 1
#		define KMP_WINDOWS 1
#		define KMP_INTRINSICS 1
#		define KMP_ARCHSTR ""
#   elif defined(_M_X64)
#       define KMP_X64 1
#       define KMP_WINDOWS 1
#		define KMP_INTRINSICS 1
#		define KMP_ARCHSTR "64"
#	elif defined(_M_PPC)
#		define KMP_PPC 1
#		define KMP_XBOX360 1
#		define KMP_VMX 1
#		define KMP_INTRINSICS 1
#		define KMP_ARCHSTR "X360"
#   elif defined(_M_ARM)
#		define KMP_ARM 1
#       define KMP_ARM_NEON 1
#		define KMP_INTRINSICS 1
#		define KMP_ARCHSTR "Arm"
#	else
#		error "Unknown platform"
#	endif
#   if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP))
#		define KMP_PC_APP 1
#		define KMP_FAMILY_STR "Metro"
#	endif
#   if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))
#		define KMP_PHONE_APP 1
#		undef KMP_ARCHSTR
#		define KMP_ARCHSTR ""
#		define KMP_FAMILY_STR "Phone"
#	endif
#   if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
#		define KMP_DESKTOP_APP 1
#		define KMP_FAMILY_STR ""
#	endif
#endif

#if defined(_MSC_VER) && !defined(_M_ARM) && (!_MANAGED) && (!_M_CEE) && (!defined(_M_IX86_FP) || (_M_IX86_FP > 1)) && !defined(KMP_NO_INTRINSICS) && !defined(KMP_VECTORCALL)
#if ((_MSC_FULL_VER >= 170065501) && (_MSC_VER < 1800)) || (_MSC_FULL_VER >= 180020418)
#define KMP_VECTORCALL 1
#endif
#endif

#if defined(KMP_INTRINSICS) && !defined(KMP_ARM_NEON_INTRINSICS) && !defined(KMP_SSE_INTRINSICS) && !defined(KMP_VMX128_INTRINSICS) && !defined(KMP_NO_INTRINSICS)
#if defined(KMP_AVX_BUILD)
// _WIN32 _WIN64
#if defined(KMP_X86) || defined(KMP_X64)
#define KMP_AVX_INTRINSICS 1
#endif
#elif defined(KMP_X86) || defined(KMP_X64) || defined(KMP_XBOXONE)
// _WIN32 _WIN64 XBOX_ONE
#define KMP_SSE_INTRINSICS 1
#elif defined(KMP_XBOX360)
// XBOX_360
#define KMP_VMX128_INTRINSICS 1
#elif defined(KMP_ARM)
// _ARM
#define KMP_ARM_NEON_INTRINSICS 1
#elif !defined(KMP_NO_INTRINSICS)
# pragma error "KMP does not support this target"
#endif
#endif // !KMP_ARM_NEON_INTRINSICS_ && !KMP_SSE_INTRINSICS_ && !KMP_VMX128_INTRINSICS_ && !KMP_NO_INTRINSICS_

#if !defined(KMP_INTRINSICS_SUPPORT) && (defined(KMP_ARM_NEON_INTRINSICS) || defined(KMP_SSE_INTRINSICS) || defined(KMP_AVX_INTRINSICS) || defined(KMP_VMX128_INTRINSICS)) && !defined(KMP_NO_INTRINSICS)
#define KMP_INTRINSICS_SUPPORT 1
#endif

#if defined(KMP_INTRINSICS_SUPPORT) && (_MSC_VER <= 1500)
#pragma error "Implemented Intrinsics not supported in target compiler"
#endif

// check that exactly one of NDEBUG and _DEBUG is defined
#if (defined(NDEBUG) && defined(_DEBUG) || ((defined(NDEBUG) && defined(DEBUG))))
# pragma error "Exactly one of NDEBUG and _DEBUG needs to be defined by preprocessor"
#endif

// make sure KMP_DEBUG is defined in all _DEBUG configurations as well
#if !defined(KMP_DEBUG) && (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG)
#define KMP_DEBUG 1
#endif

#ifdef KMP_DEBUG
#define KMP_B_T_STR  "_d"
#else
#define KMP_B_T_STR  ""
#endif

#define OMP_50_ENABLED 0
#define OMP_41_ENABLED 0
#define OMP_40_ENABLED 0
#define OMP_30_ENABLED 0

#if OMP_VERSION == 50
#undef OMP_50_ENABLED
#define OMP_50_ENABLED 1
#undef OMP_41_ENABLED
#define OMP_41_ENABLED 1
#undef OMP_40_ENABLED
#define OMP_40_ENABLED 1
#undef OMP_30_ENABLED
#define OMP_30_ENABLED 1
#elif OMP_VERSION == 41
#undef OMP_50_ENABLED
#define OMP_50_ENABLED 0
#undef OMP_41_ENABLED
#define OMP_41_ENABLED 1
#undef OMP_40_ENABLED
#define OMP_40_ENABLED 1
#undef OMP_30_ENABLED
#define OMP_30_ENABLED 1
#elif OMP_VERSION == 40
#undef OMP_50_ENABLED
#define OMP_50_ENABLED 0
#undef OMP_41_ENABLED
#define OMP_41_ENABLED 0
#undef OMP_40_ENABLED
#define OMP_40_ENABLED 1
#undef OMP_30_ENABLED
#define OMP_30_ENABLED 1
#elif OMP_VERSION == 30
#undef OMP_50_ENABLED
#define OMP_50_ENABLED 0
#undef OMP_41_ENABLED
#define OMP_41_ENABLED 0
#undef OMP_40_ENABLED
#define OMP_40_ENABLED 0
#undef OMP_30_ENABLED
#define OMP_30_ENABLED 1
#endif

#endif // KMP_PREPROCESSOR_H
